import { useUserInfoStore } from '@/stores/user';
import { BASE_URL, CHANNEL, SECRET_KEY, VERSION } from './config';
import md5 from 'md5';

const TIME_OUT = 30 * 1000; // 超时时间
const CONTENT_TYPE = 'application/x-www-form-urlencoded';

type METHOD = 'POST' | 'GET';

export function get<T>(
  url: string,
  params?: { [key: string]: any }
): Promise<T> {
  return request<T>(url, params, 'GET');
}

export function post<T>(
  url: string,
  params?: { [key: string]: any }
): Promise<T> {
  return request<T>(url, params, 'POST');
}

export function request<T>(
  url: string,
  params?: { [key: string]: any },
  method: METHOD = 'POST'
): Promise<T> {
  const tmpUrl = url.indexOf('http') == -1 ? BASE_URL + url : url;
  const header: { [key: string]: any } = {};
  header['content-type'] = CONTENT_TYPE;

  logDebug('服务器请求url', tmpUrl);

  const tmpData = initCommonParams(params);

  return new Promise((resolve, reject) => {
    uni.request({
      url: tmpUrl,
      header,
      timeout: TIME_OUT,
      method,
      data: tmpData,
      success: function (res) {
        const data: { [key: string]: any } = res.data as { [key: string]: any };
        const status = data.status;
        // 处理服务器返回报错数据
        if (status === 0 && data.msg) {
          logDebug('服务器请求出错了', data.msg);
          return reject(data.msg);
        }
        logDebug('数据请求成功', data.data);
        resolve(data.data as T);
      },
      fail: function (e) {
        logDebug('服务器请求出错了', e);
        reject(e);
      },
    });
  });
}

function logDebug(title: string, result: any) {
  if (process.env.NODE_ENV === 'development') {
    console.log(title + ': ' + JSON.stringify(result));
  }
}

/**
 * 初始化参数
 */
function initCommonParams(params?: { [key: string]: any }): {
  [key: string]: any;
} {
  const userStore = useUserInfoStore();

  const tmpParams = params ?? {};
  tmpParams.channel = CHANNEL;
  tmpParams.version = VERSION;
  tmpParams.timestamp = Math.floor(new Date().getTime() / 1000);
  if (userStore.isLogin()) {
    tmpParams.token = userStore.userInfo.token;
  }
  // sign 一定要放在最后
  tmpParams.sign = signParams(tmpParams);

  logDebug('服务器请求参数', tmpParams);

  return tmpParams;
}

/**
 * 对参数进行签名
 */
function signParams(params: { [key: string]: any }): string {
  const secret = SECRET_KEY;
  const keys = Object.keys(params);
  keys.sort();
  let paramStr = '';
  for (let i = 0; i < keys.length; i++) {
    const key = keys[i];
    paramStr += (i === 0 ? '' : '&') + key + '=' + params[key];
  }
  const res = secret + paramStr;

  return md5(res);
}
